package com.fast.alden.admin.web.controller.system;

import com.fast.alden.admin.annotation.OperationLog;
import com.fast.alden.admin.entity.dto.AssignMenuRoleParam;
import com.fast.alden.admin.service.SysMenuService;
import com.fast.alden.data.model.SysMenu;
import com.fast.alden.data.model.SysOperationType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 菜单管理控制器
 */
@Tag(name = "SysMenuController", description = "菜单管理（精确到按钮）")
@RestController
@RequestMapping("/menu")
public class SysMenuController {
    @Resource
    private SysMenuService menuService;

    @Operation(summary = "分页查询")
    @PostMapping("/page")
    public Page<SysMenu> page(@RequestBody @Nullable SysMenu searchVo,
                              @RequestParam(name = "no", defaultValue = "0") int no,
                              @RequestParam(name = "size", defaultValue = "10") int size
    ) {
        return menuService.search(searchVo, PageRequest.of(no, size, Sort.by(Sort.Direction.DESC, "createdTime")));
    }

    @Operation(summary = "树表查询", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @PostMapping("/tree-list")
    public List<SysMenu> treeList() {
        return menuService.tree();
    }

    @Operation(summary = "根据ID查询")
    @GetMapping("/retrieve/{id}")
    public SysMenu retrieve(@PathVariable("id") Long id) {
        return menuService.retrieve(id);
    }

    @OperationLog(title = "菜单管理", type = SysOperationType.CREATE)
    @Operation(summary = "创建菜单")
    @PostMapping("/create")
    public Long create(@RequestBody SysMenu menu) {
        return menuService.create(menu).getId();
    }

    @OperationLog(title = "菜单管理", type = SysOperationType.UPDATE)
    @Operation(summary = "修改菜单", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @PutMapping("/update")
    public void update(@RequestBody SysMenu role) {
        menuService.update(role);
    }

    @OperationLog(title = "菜单管理", type = SysOperationType.DELETE)
    @Operation(summary = "删除菜单", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @DeleteMapping("/remove")
    public void remove(@RequestParam("ids") List<Long> ids) {
        menuService.remove(ids);
    }

    /**
     * 查找已分配的角色
     *
     * @param roleId
     * @return
     */
    @Operation(summary = "查找指定角色已分配的菜单列表", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @GetMapping("/{roleId}/menus")
    public List<SysMenu> findMenusByRoleId(@PathVariable("roleId") Long roleId) {
        return menuService.findMenusByRoleId(roleId);
    }

    /**
     * 分配菜单
     */
    @OperationLog(title = "菜单管理", type = SysOperationType.GRANT)
    @Operation(summary = "为指定角色分配指定菜单列表权限", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @PostMapping("/assign")
    public void assign(@RequestBody @Validated AssignMenuRoleParam param) {
        menuService.assign(param.getRoleId(), param.getMenuIds());
    }

    /**
     * 取消分配菜单
     */
    @OperationLog(title = "菜单管理", type = SysOperationType.GRANT)
    @Operation(summary = "为指定角色移除指定菜单列表权限", security = @SecurityRequirement(name = "openApiSecurityScheme"))
    @PostMapping("/cancel-assign")
    public void cancelAssign(@RequestBody @Validated AssignMenuRoleParam param) {
        menuService.cancelAssign(param.getRoleId(), param.getMenuIds());
    }
}
